package com.tukez.tmdb

import org.specs2._
import org.specs2.specification.Scope
import org.specs2.mutable.Specification
import org.specs2.mock.Mockito
import com.tukez.tmdb.http.IHttpClient
import com.tukez.tmdb.http.HttpResponse
import com.tukez.tmdb.util.{ DateTimeSerializer, LocalDateSerializer, DurationSerializer }
import net.liftweb.json
import java.text.SimpleDateFormat
import com.tukez.tmdb.model._
import org.joda.time.LocalDate
import org.joda.time.DateTime
import scala.io.Source
import org.joda.time.DateTimeZone
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
abstract class TMDbSpecBase extends Specification with Mockito with ScalaCheck {

  trait context extends Scope {
    val http = mock[IHttpClient]
    val tmdb = TMDb("APIKEY", http = http)
  }

  trait httpGet extends context {
    http.get(anyString) returns HttpResponse(200, "")
  }

  def throwExceptionWhenHttpResponseStatusCodeIsOtherThan200[A](f: TMDb => A) = {
    "throw exception when http response status code is other than OK(200)" in check { (statusCode: Int) =>
      val http = mock[IHttpClient]
      val tmdb = TMDb("APIKEY", http = http)
      (statusCode != 201) ==> {
        http.get(anyString) returns HttpResponse(statusCode, "")
        f(tmdb) must throwA[TMDbException]
      }
    }
  }

  private val baseUrl = "http://api.themoviedb.org"
  private val apiVersion = "2.1"
  private val defaultLanguage = "en"
  private val apiType = "json"
  protected val apikey = "APIKEY"
  protected def urlFor(method: String) = baseUrl + "/" + apiVersion + "/" + method + "/" + defaultLanguage + "/" + apiType + "/" + apikey
  protected def urlWithLanguageFor(method: String, language: String = "en") = baseUrl + "/" + apiVersion + "/" + method + "/" + language + "/" + apiType + "/" + apikey
  protected def urlFor(method: String, params: String*) = baseUrl + "/" + apiVersion + "/" + method + "/" + defaultLanguage + "/" + apiType + "/" + apikey + "?" + params.mkString("&")

  implicit val jsonFormats = new json.DefaultFormats {
    override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  } + DateTimeSerializer + LocalDateSerializer + DurationSerializer

  protected def readJson(filename: String) = Source.fromInputStream(this.getClass.getResourceAsStream(filename)).getLines.mkString
}
